using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Microsoft.Extensions.Logging;
using Volo.Abp.ObjectMapping;
using Microsoft.AspNetCore.Mvc;
using CKY.AgentPlatform.Conversations.Dto;

namespace CKY.AgentPlatform.Conversations
{
    /// <summary>
    /// 对话管理应用服务
    /// </summary>
    public class ConversationAppService : ApplicationService, IConversationAppService
    {
        private readonly IRepository<Conversation, Guid> _conversationRepository;
        private readonly IRepository<ConversationMessage, Guid> _messageRepository;
        private readonly ILogger<ConversationAppService> _logger;

        public ConversationAppService(
            IRepository<Conversation, Guid> conversationRepository,
            IRepository<ConversationMessage, Guid> messageRepository,
            ILogger<ConversationAppService> logger)
        {
            _conversationRepository = conversationRepository;
            _messageRepository = messageRepository;
            _logger = logger;
        }

        /// <summary>
        /// 获取对话列表
        /// </summary>
        /// <param name="input">查询参数</param>
        /// <returns>对话列表</returns>
        public async Task<PagedResultDto<ConversationDto>> GetListAsync(GetConversationListInput input)
        {
            var query = await _conversationRepository.GetQueryableAsync();

            // 应用过滤条件
            if (!string.IsNullOrWhiteSpace(input.Filter))
            {
                query = query.Where(c => c.Title.Contains(input.Filter) || c.Summary.Contains(input.Filter));
            }

            if (input.AgentId.HasValue)
            {
                query = query.Where(c => c.AgentId == input.AgentId);
            }

            if (!string.IsNullOrEmpty(input.Status))
            {
                if (Enum.TryParse<ConversationStatus>(input.Status, true, out var status))
                {
                    query = query.Where(c => c.Status == status);
                }
            }

            // 获取总数
            var totalCount = await AsyncExecuter.CountAsync(query);

            // 应用排序和分页
            query = query.OrderByDescending(c => c.EndTime)
                       .Skip(input.SkipCount)
                       .Take(input.MaxResultCount);

            var conversations = await AsyncExecuter.ToListAsync(query);
            var conversationDtos = conversations.Select(c => new ConversationDto
            {
                Id = c.Id,
                Title = c.Title,
                Description = c.Summary,
                UserId = c.UserId ?? Guid.Empty,
                AgentId = c.AgentId,
                Status = c.Status.ToString(),
                CreationTime = c.CreationTime,
                LastMessageTime = c.LastModificationTime,
                MessageCount = c.MessageCount
            }).ToList();

            return new PagedResultDto<ConversationDto>(
                totalCount,
                conversationDtos
            );
        }

        /// <summary>
        /// 获取对话详情
        /// </summary>
        /// <param name="id">对话ID</param>
        /// <returns>对话详情</returns>
        public async Task<ConversationDto> GetAsync(Guid id)
        {
            var conversation = await _conversationRepository.GetAsync(id);
            var messages = await _messageRepository.GetListAsync(m => m.ConversationId == id);

            var conversationDto = new ConversationDto
            {
                Id = conversation.Id,
                Title = conversation.Title,
                Description = conversation.Summary,
                UserId = conversation.UserId ?? Guid.Empty,
                AgentId = conversation.AgentId,
                Status = conversation.Status.ToString(),
                CreationTime = conversation.CreationTime,
                LastMessageTime = conversation.LastModificationTime,
                MessageCount = conversation.MessageCount
            };

            return conversationDto;
        }

        /// <summary>
        /// 创建对话
        /// </summary>
        /// <param name="input">创建参数</param>
        /// <returns>创建的对话</returns>
        public async Task<ConversationDto> CreateAsync(CreateConversationInput input)
        {
            var conversation = new Conversation(
                GuidGenerator.Create(),
                input.Title,
                input.AgentId,
                CurrentUser.Id,
                "" // System prompt is not in the DTO
            );

            await _conversationRepository.InsertAsync(conversation);

            _logger.LogInformation("创建新对话: {ConversationId}, 标题: {Title}", conversation.Id, conversation.Title);

            return new ConversationDto
            {
                Id = conversation.Id,
                Title = conversation.Title,
                Description = conversation.Summary,
                UserId = conversation.UserId ?? Guid.Empty,
                AgentId = conversation.AgentId,
                Status = conversation.Status.ToString(),
                CreationTime = conversation.CreationTime,
                LastMessageTime = conversation.LastModificationTime,
                MessageCount = conversation.MessageCount
            };
        }

        /// <summary>
        /// 更新对话
        /// </summary>
        /// <param name="id">对话ID</param>
        /// <param name="input">更新参数</param>
        /// <returns>更新后的对话</returns>
        public async Task<ConversationDto> UpdateAsync(Guid id, UpdateConversationInput input)
        {
            var conversation = await _conversationRepository.GetAsync(id);

            conversation.Title = input.Title;
            conversation.Summary = input.Description;
            conversation.Tags = input.Tags;

            // Update status based on the Status string
            if (!string.IsNullOrEmpty(input.Status))
            {
                if (input.Status.ToLower() == "active")
                    conversation.Status = ConversationStatus.Active;
                else if (input.Status.ToLower() == "completed")
                    conversation.Status = ConversationStatus.Completed;
                else if (input.Status.ToLower() == "cancelled")
                    conversation.Status = ConversationStatus.Cancelled;
                else if (input.Status.ToLower() == "error")
                    conversation.Status = ConversationStatus.Error;
            }

            await _conversationRepository.UpdateAsync(conversation);

            _logger.LogInformation("更新对话: {ConversationId}, 标题: {Title}", conversation.Id, conversation.Title);

            return new ConversationDto
            {
                Id = conversation.Id,
                Title = conversation.Title,
                Description = conversation.Summary,
                UserId = conversation.UserId ?? Guid.Empty,
                AgentId = conversation.AgentId,
                Status = conversation.Status.ToString(),
                CreationTime = conversation.CreationTime,
                LastMessageTime = conversation.LastModificationTime,
                MessageCount = conversation.MessageCount
            };
        }

        /// <summary>
        /// 删除对话
        /// </summary>
        /// <param name="id">对话ID</param>
        public async Task DeleteAsync(Guid id)
        {
            var conversation = await _conversationRepository.GetAsync(id);
            
            // 删除相关消息
            var messages = await _messageRepository.GetListAsync(m => m.ConversationId == id);
            foreach (var message in messages)
            {
                await _messageRepository.DeleteAsync(message);
            }
            
            // 删除对话
            await _conversationRepository.DeleteAsync(conversation);

            _logger.LogInformation("删除对话: {ConversationId}, 标题: {Title}", conversation.Id, conversation.Title);
        }

        /// <summary>
        /// 添加消息到对话
        /// </summary>
        /// <param name="conversationId">对话ID</param>
        /// <param name="input">消息内容</param>
        /// <returns>添加的消息</returns>
        public async Task<ConversationMessageDto> AddMessageAsync(Guid conversationId, CreateConversationMessageInput input)
        {
            var conversation = await _conversationRepository.GetAsync(conversationId);

            // 获取当前消息的数量作为order
            var currentMessageCount = await _messageRepository.CountAsync(m => m.ConversationId == conversationId);

            MessageRole role = input.Role == "user" ? MessageRole.User : input.Role == "assistant" ? MessageRole.Assistant : MessageRole.System;

            var message = new ConversationMessage(
                GuidGenerator.Create(),
                conversationId,
                role,
                input.Content,
                currentMessageCount + 1
            );

            await _messageRepository.InsertAsync(message);

            // 更新对话状态
            conversation.Status = ConversationStatus.Active;
            await _conversationRepository.UpdateAsync(conversation);

            _logger.LogInformation("添加消息到对话: {ConversationId}, 角色: {Role}", conversationId, input.Role);

            return ObjectMapper.Map<ConversationMessage, ConversationMessageDto>(message);
        }

        /// <summary>
        /// 获取对话消息列表
        /// </summary>
        /// <param name="conversationId">对话ID</param>
        /// <returns>消息列表</returns>
        public async Task<List<ConversationMessageDto>> GetMessagesAsync(Guid conversationId)
        {
            var messages = await _messageRepository.GetListAsync(m => m.ConversationId == conversationId);
            return ObjectMapper.Map<List<ConversationMessage>, List<ConversationMessageDto>>(messages);
        }

        /// <summary>
        /// 更新消息内容
        /// </summary>
        /// <param name="messageId">消息ID</param>
        /// <param name="input">更新参数</param>
        /// <returns>更新后的消息</returns>
        public async Task<ConversationMessageDto> UpdateMessageAsync(Guid messageId, UpdateConversationMessageInput input)
        {
            var message = await _messageRepository.GetAsync(messageId);

            message.Content = input.Content;
            if (input.Metadata != null)
            {
                // 将metadata序列化为JSON字符串存储
                message.Metadata = System.Text.Json.JsonSerializer.Serialize(input.Metadata);
            }

            await _messageRepository.UpdateAsync(message);

            _logger.LogInformation("更新消息: {MessageId}", messageId);

            return ObjectMapper.Map<ConversationMessage, ConversationMessageDto>(message);
        }

        /// <summary>
        /// 删除消息
        /// </summary>
        /// <param name="messageId">消息ID</param>
        public async Task DeleteMessageAsync(Guid messageId)
        {
            var message = await _messageRepository.GetAsync(messageId);
            await _messageRepository.DeleteAsync(message);

            _logger.LogInformation("删除消息: {MessageId}", messageId);
        }

        /// <summary>
        /// 获取对话统计信息
        /// </summary>
        /// <param name="agentId">智能体ID（可选）</param>
        /// <returns>统计信息</returns>
        [HttpGet("api/app/conversation/statistics")]
        public async Task<ConversationStatisticsDto> GetStatisticsAsync(Guid? agentId = null)
        {
            var query = await _conversationRepository.GetQueryableAsync();

            if (agentId.HasValue)
            {
                query = query.Where(c => c.AgentId == agentId.Value);
            }

            var totalConversations = await AsyncExecuter.CountAsync(query);
            var activeConversations = await AsyncExecuter.CountAsync(query.Where(c => c.Status == ConversationStatus.Active));
            var totalMessages = await AsyncExecuter.CountAsync(
                from c in query
                join m in await _messageRepository.GetQueryableAsync() on c.Id equals m.ConversationId
                select m
            );

            return new ConversationStatisticsDto
            {
                TotalConversations = (int)totalConversations,
                ActiveConversations = (int)activeConversations,
                TotalMessages = totalMessages,
                StatisticsTimestamp = DateTime.UtcNow
            };
        }

  
        /// <summary>
        /// 关闭对话
        /// </summary>
        /// <param name="id">对话ID</param>
        public async Task CloseAsync(Guid id)
        {
            var conversation = await _conversationRepository.GetAsync(id);
            conversation.Status = ConversationStatus.Completed;
            conversation.EndTime = DateTime.UtcNow;
            await _conversationRepository.UpdateAsync(conversation);

            _logger.LogInformation("关闭对话: {ConversationId}", id);
        }

        /// <summary>
        /// 重新打开对话
        /// </summary>
        /// <param name="id">对话ID</param>
        public async Task ReopenAsync(Guid id)
        {
            var conversation = await _conversationRepository.GetAsync(id);
            conversation.Status = ConversationStatus.Active;
            conversation.EndTime = null;
            await _conversationRepository.UpdateAsync(conversation);

            _logger.LogInformation("重新打开对话: {ConversationId}", id);
        }
    }
}